package com.gitee.huanminabc.utils_tools.file_tool.pdfbox;

import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripperByArea;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @description: 将pdf内的图片提取出来
 * @author: huanmin
 * @create: 2025-04-22 18:52
 **/
public class PDFToImageUtil {

    //提取PDF中的所有图片
    public static List<byte[]> extractImages(byte[] pdfBytes) {
        try {
            List<byte[]> images = new ArrayList<>();
            try (PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfBytes))) {
                for (PDPage page : document.getPages()) {
                    for (COSName xObjectName : page.getResources().getXObjectNames()) {
                        PDXObject xObject = page.getResources().getXObject(xObjectName);

                        if (xObject instanceof PDImageXObject) {
                            PDImageXObject imageXObject = (PDImageXObject) xObject;
                            try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                                BufferedImage bImage = imageXObject.getImage();
                                ImageIO.write(bImage, "png", outputStream); // Save as PNG
                                images.add(outputStream.toByteArray());
                            }
                        }
                    }
                }
            }
            return images;
        } catch (IOException e) {
            throw  new RuntimeException("提取图片失败", e);
        }
    }

    //pdfbox 把每一页都转换为图片
    public static List<byte[]> eachPageToImage(byte[] pdfBytes) {
        List<byte[]> images = new ArrayList<>();
        try (PDDocument document = PDDocument.load(new ByteArrayInputStream(pdfBytes))) {
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            int pageCount = document.getNumberOfPages();
            // 用于空白页检测的文本提取器
            PDFTextStripperByArea stripper = new PDFTextStripperByArea();
            stripper.setSortByPosition(true);
            for (int i = 0; i < pageCount; i++) {
                PDPage page = document.getPage(i);
                // 检查是否为空白页
                if (isBlankPageWithoutRendering(page, stripper)) {
                    continue;
                }
                BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(i, 300); // 300 DPI
                try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                    ImageIO.write(bufferedImage, "png", outputStream); // Save as PNG
                    images.add(outputStream.toByteArray());
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("每页转换为图片失败", e);
        }
        return images;
    }


    /**
     * 检测空白页
     */
    private static boolean isBlankPageWithoutRendering(PDPage page, PDFTextStripperByArea stripper) throws IOException {
        // 1. 检查页面是否有文本内容
        Rectangle rect = new Rectangle(0, 0, 10000, 10000); // 大矩形确保覆盖整个页面
        stripper.addRegion("region", rect);

        stripper.extractRegions(page);
        String text = stripper.getTextForRegion("region");

        if (text != null && !text.trim().isEmpty()) {
            return false; // 有文本内容，不是空白页
        }

        // 2. 检查页面是否有图像
        PDResources resources = page.getResources();
        if (resources != null) {
            for (COSName xObjectName : resources.getXObjectNames()) {
                PDXObject xObject = resources.getXObject(xObjectName);
                if (xObject instanceof PDImageXObject) {
                    return false; // 有图像，不是空白页
                }
            }
        }

        // 3. 检查页面尺寸是否极小（某些PDF会有微小的空白页）
        PDRectangle mediaBox = page.getMediaBox();
        if (mediaBox.getWidth() < 10 && mediaBox.getHeight() < 10) {
            return true; // 页面尺寸极小，视为空白页
        }
        return true; // 经过以上检查，判定为空白页
    }


    public static void main(String[] args) {
        try {
            // 读取PDF文件为字节数组
            byte[] pdfBytes = Files.readAllBytes(Paths.get("/Users/anminhu/Downloads/CgAC3WhCeOmAX3UpAAI420FJZ1Y731.pdf"));
//            byte[] pdfBytes = Files.readAllBytes(Paths.get("/Users/anminhu/Downloads/11.pdf"));

            // 调用工具类提取图片
            List<byte[]> images = PDFToImageUtil.eachPageToImage(pdfBytes);

            // 保存提取的图片到文件
            for (int i = 0; i < images.size(); i++) {
                Files.write(Paths.get("image" + (i + 1) + ".png"), images.get(i));
            }

            System.out.println("提取了 " + images.size() + " 张图片！");
        } catch (IOException e) {
            e.printStackTrace();

        }
    }
}